package com.du.controller;

import com.du.domain.Item;
import com.du.enums.ExceptionEnum;
import com.du.exception.SsmException;
import com.du.service.ItemService;
import com.du.vo.ResultVO;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

/**
 * 商品信息Controller层
 */
@Controller
@RequestMapping("/item")
@Slf4j
public class ItemController {
    @Autowired
    private ItemService itemService;

    //图片大小信息
    @Value("${pic.maxSize}")
    private Long picMaxSize;

    //图片格式信息
    @Value("${pic.types}")
    private String types;

    //展示所有商品及根据名称动态展示商品
    @GetMapping("/list")
    public String showAllItems(String name, Model model,
                               @RequestParam(defaultValue ="1") Integer page,
                               @RequestParam(defaultValue = "5") Integer size){

        //调用Service查询
        PageInfo<Item> pageInfo = itemService.selectItemsByLimit(name, page, size);
        //将数据放到request域中
        //页面信息pageInfo
        model.addAttribute("pageInfo",pageInfo);
        //查询条件回显：name
        model.addAttribute("name",name);
        //转发页面
        return "item/item_list";
    }

    //转发到添加商品页面
    @GetMapping("/add-ui")
    public String AddUi(){
        return "item/item_add";
    }

    //添加商品
    @PostMapping("/add")
    @ResponseBody
    public ResultVO addItem(MultipartFile picFile, HttpServletRequest req, @Validated Item item, BindingResult br) throws IOException {
        //	1. 添加配置信息,将CommonsMultipartResolver注入到spring容器.
        //	2. 在controller的方法参数上使用MultipartFile对象接收文件上传项.
        //	3. 接收普通表单项Item item,并校验.
        //	4. 文件上传项校验
        if (picFile==null||picFile.getSize()==0){
            //没有文件上传项
            log.info("【添加商品】 必需上传商品图片信息！！");
            throw new SsmException(ExceptionEnum.REQUEST_PARAMS.getCode(),"必需上传商品图片信息!");
        }
        //	5.1 大小判断.
        if (picFile.getSize()>picMaxSize){
            log.info("【添加商品】 文件过大！请重新上传！！");
            throw new SsmException(ExceptionEnum.PIC_OVERSIZE);

        }
        //	5.2 类型判断.
        List<String> typesList = Arrays.asList(types.split(","));
        String filename = picFile.getOriginalFilename();
        String typeName = filename.substring(filename.lastIndexOf(".") + 1).toLowerCase();
        if (!typesList.contains(typeName)){
            //图片类型错误
            log.info("【添加商品】 不支持的图片类型！！");
            throw new SsmException(ExceptionEnum.PIC_TYPE_ERROR);
        }
        //	5.3 是否损坏.
        BufferedImage image = ImageIO.read(picFile.getInputStream());
        if (image==null){
            log.info("【添加商品】 图片已损坏！！");
            throw new SsmException(ExceptionEnum.PIC_CONTEXT_ERROR);
        }
        //	5.4 新名字.
        String newName= UUID.randomUUID().toString().replaceAll("-", "")+"_"+filename;
        //拼接本地文件保存路径   //static/images/
        String path=req.getServletContext().getRealPath("/")+"static/images/"+newName;
        //封装成File类型，判断该目录是否存在
        File file = new File(path);
        if (!file.getParentFile().exists()){
            //目录不存在，创建新目录
            file.getParentFile().mkdirs();
        }
        //	5.5 保存到本地.
        IOUtils.copy(picFile.getInputStream(), new FileOutputStream(file));
        //	5.6 将图片的访问路径设置到item对象中.
        String picPath=req.getContextPath()+"/static/images/"+newName;
        item.setPic(picPath);
        //	6. 校验普通表单项.
        if (br.hasErrors()){
            String msg = br.getFieldError().getDefaultMessage();
            log.info("【添加商品】 请求参数错误！！ item={},msg={}",item,msg);
            throw new SsmException(ExceptionEnum.REQUEST_PARAMS.getCode(),msg);
        }
        //	7. 调用serivce保存.
        itemService.addItem(item);
        //	8. 响应数据.
        return new ResultVO(0, "成功", null);

    }

    //删除商品
    @DeleteMapping("/delete/{id}")
    @ResponseBody
    public ResultVO delete(@PathVariable Integer id){
        itemService.deleteItem(id);
        return new ResultVO(0, "成功！", null);
    }

    //修改商品回显数据
    @GetMapping("update-ui")
    public String updateUI(Integer id,Model model){
        //调用Service查询当前商品信息
        Item item = itemService.selectItemById(id);
        //将数据放到request域中
        model.addAttribute("item",item);
        //转发到修改页面
        return "item/item_update";
    }

    //修改商品
    @PostMapping("/update")
    @ResponseBody
    public ResultVO update(MultipartFile picFile,HttpServletRequest req,@Validated Item item,BindingResult br) throws IOException {
        //文件上传项校验
        if (picFile==null||picFile.getSize()==0){
            //没有文件上传项
            log.info("【修改商品信息】 必需上传商品图片信息！！");
            throw new SsmException(ExceptionEnum.REQUEST_PARAMS.getCode(),"必需上传商品图片信息!");
        }
        String newName= UUID.randomUUID().toString().replaceAll("-", "")+"_"+picFile.getOriginalFilename();
        //拼接本地文件保存路径   //static/images/
        String path=req.getServletContext().getRealPath("/")+"static/images/"+newName;
        //封装成File类型，判断该目录是否存在
        File file = new File(path);
        if (!file.getParentFile().exists()){
            //目录不存在，创建新目录
            file.getParentFile().mkdirs();
        }
        //保存到本地.
        IOUtils.copy(picFile.getInputStream(), new FileOutputStream(file));
        //将图片的访问路径设置到item对象中.
        String picPath=req.getContextPath()+"/static/images/"+newName;
        item.setPic(picPath);
        //校验普通表单项.
        if (br.hasErrors()){
            String msg = br.getFieldError().getDefaultMessage();
            log.info("【修改商品信息】 请求参数错误！！ item={},msg={}",item,msg);
            throw new SsmException(ExceptionEnum.REQUEST_PARAMS.getCode(),msg);
        }
        //执行修改
        itemService.updateItem(item);
        //返回
        return new ResultVO(0, "成功", null);
    }

}
